#!/usr/bin/env ruby
#
# Generate a Ruby version of an RDFa vocabulary to be directly accessible from RDF::RDFa::Context
require 'rubygems'
$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", 'lib')))
require 'rdf/turtle'
require 'rdf/rdfa'
require 'rdf/rdfxml'
require 'getoptlong'
require 'open-uri'

def help
  puts "Usage: #{$0} [options] file-or-uri ..."
  puts "Options:"
  puts "      --dump:               Dump raw output, otherwise serialize to Ruby"
  puts "      --debug:              Display detailed debug output"
  puts "      --verbose:            Verbose processing"
  puts "      --output:             Write to file"
  puts "      --help,-?:            This message"
  exit(0)
end

dump = false
output = STDOUT

opts = GetoptLong.new(
  ["--debug", GetoptLong::NO_ARGUMENT],
  ["--dump", GetoptLong::NO_ARGUMENT],
  ["--output", "-o", GetoptLong::REQUIRED_ARGUMENT],
  ["--verbose", GetoptLong::NO_ARGUMENT],
  ["--help", "-?", GetoptLong::NO_ARGUMENT]
)
opts.each do |opt, arg|
  case opt
  when '--verbose'  then $verbose = true
  when '--debug'    then ::RDF::RDFa::debug = true
  when '--dump'     then dump = true
  when '--output'   then output = File.open(arg, "w")
  when '--help'     then help
  end
end

help if ARGV.empty?

ARGV.each do |file|
  uri = RDF::URI(file)
  if RDF::RDFa::Context.cache[uri]
    STDERR.puts "Remove cached entry for #{uri} before attempting to parse"
    exit(1)
  end
  
  context = RDF::RDFa::Context.find(uri)
  if dump
    puts context.inspect
  else
    context_short = uri.to_s.split("/").last.gsub(/[^\w]/, '_')
    preceeding = '        '
    output.puts  <<START
# This file is automatically generated by #{__FILE__}
# RDFa context for #{file}

class RDF::RDFa::Context
  def self.find_with_#{context_short}(uri)
    if uri.to_s == "#{file}"
      @_#{context_short}_prof ||= RDF::RDFa::Context.new(RDF::URI("#{file}"), {
START

    output.puts %{#{preceeding}vocabulary: "#{context.vocabulary},"} if context.vocabulary
    
    [:prefixes, :terms].each do |t|
      hash = context.send(t)
      key_width = hash.keys.inject(0) {|width, k| k.inspect.length > width ? k.inspect.length : width}
      unless hash.empty?
        output.puts %(#{preceeding}#{t}: {)
          hash.keys.map(&:to_s).sort.each do |k|
            v = hash[k.to_sym]
            output.printf(%(#{preceeding}  %s:%*s%s,\n), k, -key_width + k.length, "", v.inspect)
          end
        output.puts %(#{preceeding}},)
      end
    end
    
    output.puts <<END
      })
    else
      find_without_#{context_short}(uri)
    end
  end

  class << self
    ##
    # Override find to return this context, if matched
    alias_method :find_without_#{context_short}, :find
    alias_method :find, :find_with_#{context_short}
  end
end
END

  end
end
